package vip.xiaonuo.modular.cms.controller;

import cn.hutool.extra.template.TemplateUtil;
import cn.hutool.extra.template.engine.beetl.BeetlUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.beetl.core.Configuration;
import org.beetl.core.GroupTemplate;
import org.beetl.core.Template;
import org.beetl.core.resource.FileResourceLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.HttpResource;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.core.pojo.response.ResponseData;
import vip.xiaonuo.modular.cms.config.PublicServiceHolder;
import vip.xiaonuo.modular.cms.entity.*;
import vip.xiaonuo.modular.cms.node.CatalogBaseTreeNode;
import vip.xiaonuo.modular.cms.param.CatalogParam;
import vip.xiaonuo.modular.cms.service.CatalogService;
import vip.xiaonuo.modular.cms.service.PublicApiService;
import vip.xiaonuo.modular.cms.service.TemplateService;
import vip.xiaonuo.modular.cms.service.WebService;
import vip.xiaonuo.modular.cms.vo.ArticleVO;
import vip.xiaonuo.modular.cms.vo.ProductVO;
import vip.xiaonuo.sys.modular.dict.entity.SysDictData;
import vip.xiaonuo.sys.modular.dict.entity.SysDictType;
import vip.xiaonuo.sys.modular.dict.service.SysDictDataService;
import vip.xiaonuo.sys.modular.dict.service.SysDictTypeService;
import vip.xiaonuo.sys.modular.user.service.SysUserService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ProjectName: Hitech_CMS
 * @Package: vip.xiaonuo.modular.cms.controller
 * @ClassName: PublicApiController
 * @Author: liubaihan
 * @Description: CMS开发API接口
 * @Date: 2021/8/23 14:20
 */
@Controller
@Api(tags = "CMS公开接口",value = "CMS公开接口")
public class PublicApiController {

    @Autowired
    private PublicApiService publicApiService;

    @Autowired
    private SysDictTypeService sysDictTypeService;
    
    @Autowired
    private SysDictDataService sysDictDataService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private WebService webService;

    @Autowired
    private CatalogService catalogService;

    @Value("${cms.templatePath}")
    private String templatePath;

    private String defaultFold = "default";

/**************************************************************************** 栏目接口 *****************************************************************/
    @ResponseBody
    @GetMapping("/getCatalogInfo")
    @ApiOperation("获取栏目信息")
    public ResponseData getCatalogInfo(){
        return ResponseData.success(publicApiService.getCatalogInfo());
    }

    @ResponseBody
    @GetMapping("/getCatalogChildrenById/{id}")
    @ApiOperation("获取指定栏目下的子菜单信息")
    public ResponseData getCatalogChildrenById(@PathVariable("id") String id){
        return ResponseData.success(publicApiService.getCatalogChildrenById(id));
    }

    @GetMapping("/getPage/{catalogId}")
    @ApiOperation("通过栏目ID跳转页面")
    public String toPageByCatalogId(@PathVariable("catalogId") String catalogId,HttpServletRequest request) throws IOException {
        String foldPath = (String) request.getAttribute("foldPath");
        Map basicInfo = (Map) request.getAttribute("basicInfo");
        Catalog catalog = catalogService.getById(catalogId);
        Map<String,Object> extraInfo = new HashMap<>();
        extraInfo.put("catalogId",catalogId);
        String htmlInfo = this.getHtmlInfo(basicInfo, foldPath,catalog.getPath(),extraInfo);
        request.setAttribute("htmlInfo",htmlInfo);
        return "cms/template/default/page.html";
    }

/**************************************************************************** 文章接口 *****************************************************************/
    @ResponseBody
    @GetMapping("/getArticleInfoByCatalog/{id}")
    @ApiOperation("根据栏目获取文章信息")
    public ResponseData getArticleInfoByCatalog(@PathVariable("id") String id){
        return ResponseData.success(publicApiService.getArticleInfoByCatalog(id));
    }

    @GetMapping("/getArticleContentByArticleId/{id}")
    @ApiOperation("通过文章ID获取文章信息")
    public String getArticleContentByArticleId(@PathVariable("id") String id,HttpServletRequest request) throws IOException {
        String foldPath = (String) request.getAttribute("foldPath");
        Map basicInfo = (Map) request.getAttribute("basicInfo");
        Map<String,Object> extraInfo = new HashMap<>();
        extraInfo.put("id",id);
        String htmlInfo = this.getHtmlInfo(basicInfo, foldPath,"article",extraInfo);
        request.setAttribute("htmlInfo",htmlInfo);
        return "cms/template/default/page.html";
    }

    @GetMapping("/getArticlePageList")
    @ApiOperation("获取文章列表")
    @ResponseBody
    public ResponseData getArticlePageList(@RequestParam("pageNum") Integer pageNum,
                                           @RequestParam("pageSize") Integer pageSize,
                                           @RequestParam(value = "searchText",required = false) String searchText,
                                           @RequestParam(value = "catalogId",required = false) String catalogId){
        Page<ArticleVO> pageList = this.publicApiService.getArticlePageList(pageNum, pageSize, searchText, catalogId);
        return ResponseData.success(pageList);
    }

/**************************************************************************** 产品接口 *****************************************************************/
    @ResponseBody
    @GetMapping("/getProductInfoByCatalog/{id}")
    @ApiOperation("根据栏目获取产品信息")
    public ResponseData getProductInfoByCatalog(@PathVariable("id") String id){
        return ResponseData.success(publicApiService.getProductInfoByCatalog(id));
    }

    @GetMapping("/getArticleContentByProductId/{id}")
    @ApiOperation("通过产品ID获取产品信息")
    public String getArticleContentByProductId(@PathVariable("id") String id,HttpServletRequest request) throws IOException {
        String foldPath = (String) request.getAttribute("foldPath");
        Map basicInfo = (Map) request.getAttribute("basicInfo");
        Map<String,Object> extraInfo = new HashMap<>();
        extraInfo.put("id",id);
        String htmlInfo = this.getHtmlInfo(basicInfo, foldPath,"product",extraInfo);
        request.setAttribute("htmlInfo",htmlInfo);
        return "cms/template/default/page.html";
    }

    @GetMapping("/getProductPageList")
    @ApiOperation("获取产品列表")
    @ResponseBody
    public ResponseData getProductPageList(@RequestParam("pageNum") Integer pageNum,
                                           @RequestParam("pageSize") Integer pageSize,
                                           @RequestParam(value = "searchText",required = false) String searchText,
                                           @RequestParam(value = "catalogId",required = false) String catalogId){
        Page<ProductVO> pageList = this.publicApiService.getProductPageList(pageNum, pageSize, searchText, catalogId);
        return ResponseData.success(pageList);
    }


/**************************************************************************** 页面接口 *****************************************************************/

    @ResponseBody
    @GetMapping("/getPageInfoByCatalog/{id}")
    @ApiOperation("根据栏目获取页面信息")
    public ResponseData getPageInfoByCatalog(@PathVariable("id") String id){
        return ResponseData.success(publicApiService.getPageInfoByCatalog(id));
    }

/**************************************************************************** 通知接口 *****************************************************************/

    @ResponseBody
    @GetMapping("/getNoticeType")
    @ApiOperation("获取通知类型信息")
    public ResponseData getNoticeType(){
        Long typeId = sysDictTypeService.getOne(new QueryWrapper<SysDictType>().eq("code","cms_notice_type")).getId();
        List<SysDictData> sysDictData = sysDictDataService.list(new QueryWrapper<SysDictData>().eq("type_id", typeId));
        Map<String, String> noticeTypes = sysDictData.stream().filter(e -> e.getStatus() == 0).collect(Collectors.toMap(SysDictData::getCode, SysDictData::getValue));
        return ResponseData.success(noticeTypes);
    }

    @ResponseBody
    @GetMapping("/getNoticeListByType/{type}")
    @ApiOperation("通过通知类型获取通知列表")
    public ResponseData getNoticeListByType(@PathVariable("type")String type){
        return ResponseData.success(publicApiService.getNoticeListByType(type));
    }

/**************************************************************************** 首页 *****************************************************************/
    @GetMapping("/")
    public String index( HttpServletRequest request) throws IOException {

        String foldPath = (String) request.getAttribute("foldPath");

        if(foldPath.equals(this.defaultFold)){
            return "cms/template/" + foldPath + "/index.html";
        }else{
            Map basicInfo = (Map) request.getAttribute("basicInfo");
            String htmlInfo = this.getHtmlInfo(basicInfo, foldPath,"index",null);
            request.setAttribute("htmlInfo",htmlInfo);
            return "cms/template/default/page.html";
        }

    }

    /**
     * @Description 解析模板数据
     *
     * @param basicInfo: 绑定的数据
     * @param foldPath: 模板文件夹
     * @param page: 模板文件夹下的对应的模板文件
     * @return: java.lang.String 模板解析后的HTML文本信息
     * @author: liubaihan
     * @date: 2022/8/10 22:56
     */
    private String getHtmlInfo(Map basicInfo,String foldPath,String page,Map<String,Object> extraInfo) throws IOException {

        String root = templatePath + File.separator;
        FileResourceLoader resourceLoader = new FileResourceLoader(root,"utf-8");
        Configuration cfg = Configuration.defaultConfiguration();
        GroupTemplate gt = new GroupTemplate(resourceLoader, cfg);
        // 注册公共方法
        gt.registerFunctionPackage("cmsService", new PublicServiceHolder().getPublicApiService());
        Template template = gt.getTemplate("\\"+ foldPath +"\\" + page + ".html");
        template.binding(basicInfo);
        template.binding(extraInfo);
        String htmlInfo = template.render();

        return htmlInfo;
    }
}
